home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / basic / DLL.lha / DLL / DLL.Readme < prev    next >
Encoding:
Text File  |  2000-09-11  |  24.6 KB  |  751 lines

  1.         Dynamic Linked Lists with variable length items
  2.  
  3.                         by Tony Rolfe
  4.  
  5.                   edgewater@shoalhaven.net.au
  6.  
  7.                          August 2000
  8.  
  9.                  Original code by Dave Newton
  10.  
  11.  
  12. 1. Introduction
  13.  
  14.    DLL.bb2 V3.0 By Tony Rolfe (edgewater@shoalhaven.net.au)
  15.  
  16.    Dynamic Linked Lists variable sized items for BLITZ BASIC 2
  17.  
  18.    These are a functional replacement for the List Arrays supplied with Blitz
  19.    Basic 2.
  20.  
  21.    
  22.    The fundamental difference between these routines and standard list arrays
  23.    is that there is no need to define the maximum size of a list.  Standard
  24.    Blitz Lists are defined with a command of the form
  25.  
  26.        DIM List Name.Type(MaxSize)
  27.  
  28.    With DLL the only limit on the number of entries is the amount of available
  29.    memory.   Actually, the number of entries is held in a longword variable so
  30.    the real limit is about 2,000,000,000. If anyone has problems with this
  31.    limit please let me know.
  32.  
  33.    All the original commands are replicated here.   Command names have had an
  34.    underscore added in the middle and the names fully capitalized.   Thus, the
  35.    original AddItem() command has been replaced by ADD_ITEM{}.
  36.  
  37.    A number of additional functions have also been added.
  38.  
  39.  
  40.    In this archive you should find:
  41.       This Readme file (DLL.Readme)
  42.       An AmigaGuide version of this information (dll.Guide)
  43.       DLL main routines (dll.bb2 and dll.asc)
  44.       DLL quicksort routines (dllsort.bb2 and dllsort.asc)
  45.       DLL example program (dllexample.bb2 and dllexample.asc)
  46.       Sample Fatal_Error routine (Fatal_Error.bb2 and Fatal_Error.asc)
  47.       3 Options for String Compare Routines (Compare_Strings_X.bb2 and .asc)
  48.  
  49.    All the source code is provided as tokenised (.bb2) files and plain ASCII
  50.    (.asc) files. This is so that if you have any tokenisation problems when
  51.    loading the .bb2 files you can simply load the .asc files and then save
  52.    them over the .bb2 files.
  53.  
  54.  
  55. 2. Distribution
  56.  
  57.    DLL is PD.  It is "Do-What-You-Like-Ware".
  58.  
  59.    Feel free to copy it and distribute it as you see fit.
  60.  
  61.    If, however, you make any significant changes, please forward a copy
  62.    of the changes to me so I can maintain a central copy of DLL.
  63.  
  64.    Neither Dave Newton nor I can accept any responsibility for any harm to
  65.    hardware or software caused directly or indirectly from the use of this
  66.    source code and/or extracts of this source code compiled.
  67.  
  68.    But a credit for these routines in your software/manual would be nice :).
  69.  
  70.  
  71. 3. Getting Started
  72.  
  73. Before you start to use DLL you need to make one fundamental decision:
  74.  
  75. How do you want a DLL function to behave if it encounters an unrecoverable
  76. error?   The original (Dave Newton) version of DLL had the function return
  77. a True or False value to tell if it was successful.   My own preference is
  78. for low level routines to handle their own errors and not bother returning
  79. to the calling routine if they couldn't perform their function.
  80.  
  81. Immediately following the introductory comments in DLL.bb2, is the line
  82.  
  83. #DLL_TRAP_ERRORS = 1 ;
  84.  
  85. If you wish to maintain the original version of the code, set this flag to 0.
  86. This will make you use code like:
  87.  
  88. If ADD_ITEM{*TheList}
  89.    ; success
  90. Else
  91.    ; handle the error
  92. Endif
  93.  
  94. If you wish to have each routine handle its own errors, set the flag to 1.
  95. You will need to provide a function called Fatal_Error{}, which accepts a
  96. string argument.   A sample is provided which simply displays the string
  97. and ends the program.  The above code can now be replaced with:
  98.  
  99. ADD_ITEM{*TheList}
  100.  
  101. Having set the flag, save the file as a tokenized source.   Now you can
  102. begin to use DLL.
  103.  
  104.  
  105.  
  106. For each program, you also need to decide how the sort routines should
  107. handle string comparisons.   Three string compare routines are provided.
  108. Include the required one before DLL.bb2
  109.  
  110. Compare_Strings_S.bb2   This is a case-sensitive routine ("CAT" <> "cat")
  111. Compare_Strings_I.bb2   This is a case-insensitive routine ("CAT" = "cat")
  112. Compare_Strings_IL.bb2  This is a case-insensitive routine which treats
  113.                         strings as being equal if they have different
  114.                         numbers of trailing spaces ("CAT   " = "cat")
  115.  
  116. XINCLUDE Compare_Strings_X.bb2
  117.  
  118.  
  119.  
  120. Now you need to include the dll routines somewhere near the top of your
  121. program.   This must be after the appropriate Compare_Strings routine.
  122. It does not matter whether or not the DLL routines are actually executed.
  123.  
  124. XINCLUDE "DLL.bb2"
  125.  
  126.  
  127. Next you need to create a newtype for YOUR list item. You must include
  128. a DLL node as your first variable in the newtype, otherwise you are free
  129. to do anything a newtype will allow.
  130.  
  131.  
  132. Newtype .myitem
  133.   node.dll         ; Must be the first item
  134.   namestring.s
  135.   amount.w
  136.   cost.l
  137. End Newtype
  138.  
  139.  
  140.  
  141. Then you MUST do 3 steps before you can actually use the list.
  142.  
  143. 1. Create a variable to hold a pointer to the current list item. You do
  144.    this with Deftype and it MUST create a POINTER variable type.
  145.  
  146.    Deftype .myitem *MyItemPtr
  147.  
  148.  
  149. 2. Initialize the list.   This creates the List Header and also creates a
  150.    dummy item.
  151.  
  152.    *MyList.dllhead = INIT_LIST{&*MyItemPtr,SizeOf .myitem}
  153.  
  154.    INIT_LIST is a function of the DLL includes. You must always pass the
  155.    address of your current item pointer to this routine (&*MyItemPtr). To all
  156.    other routines you must pass the head of the list as a pointer.
  157.  
  158.    You must also pass the size of your item, with Sizeof .myitem, as the
  159.    second parameter to the INIT_LIST function.  This function returns the
  160.    address of the head of the list (a dllhead type), which you save in a
  161.    pointer, so you can reference the list later on.  If you are planning to
  162.    have variable length items, you MUST set this length to at least sufficient
  163.    to include all string variables in the longest item.   If there are no
  164.    string items then a minimum of one numeric field must be included after
  165.    the node.
  166.                                                                            Ë
  167.  
  168. 3. You MUST tell DLL about all the string variables in your newtype.
  169.    This is because, when an item is killed in the list, DLL needs to know
  170.    where the string variables (if any) are, so that it can deallocate them.
  171.    Otherwise you would lose memory while the program is running.
  172.  
  173.    All you have to do is to set all your non string variables to -1 and
  174.    your string variables to "", using the dummy item created in step 2.  If
  175.    you have a fixed array [] in the item, you must set all array items to
  176.    -1 or "" as well).  You MUST do this even if there are no strings in the
  177.    NewType.
  178.  
  179.    In the above example, use the following code:
  180.  
  181.    *MyItemPtr\\namestring="",-1,-1
  182.    SET_STRING_POSITIONS{*MyList}
  183.  
  184. Now your list is ready for use. Be aware that the current item doesn't
  185. exist yet, you are simply pointing at the head of the list. So don't
  186. access any of the item variables, until you have used one of the add item
  187. routines.
  188.  
  189. If you want more than one DLL list in your program, repeat steps 1 - 3
  190. above for each list.
  191.  
  192.  
  193. 4. All the Functions
  194.  
  195. 4.1. ADD_FIRST
  196.  
  197. ret.b = ADD_FIRST{*listhead.dllhead,itemsize.l} (with #DLL_TRAP_ERRORS = 0)
  198.  
  199. ADD_FIRST{*listhead.dllhead,itemsize.l} (with #DLL_TRAP_ERRORS = 1)
  200.  
  201. Adds a new (blank) item as the first item in the list. If a function,
  202. it will return true if it successfully added an item, otherwise it returns
  203. false.
  204.  
  205. If an item was added, the current item pointer (your list pointer variable)
  206. will point to the newly added item.
  207.  
  208.  Same as ADD_ITEM, except that it inserts the new item as the last item in
  209. the list.
  210.  
  211. 4.2. ADD_ITEM
  212.  
  213. ret.b = ADD_ITEM{*listhead.dllhead,itemsize.l} (with #DLL_TRAP_ERRORS = 0)
  214.  
  215. ADD_ITEM{*listhead.dllhead,itemsize.l} (with #DLL_TRAP_ERRORS = 1)
  216.  
  217. Adds a new (blank) item to the list, at the current position. If a function,
  218. it will return true if it successfully added an item, otherwise it returns
  219. false.
  220.  
  221. If an item was added, the current item pointer (your list pointer variable)
  222. will point to the newly added item.
  223.  
  224. 4.3. ADD_LAST
  225.  
  226. ret.b = ADD_LAST{*listhead.dllhead,itemsize.l} (with #DLL_TRAP_ERRORS = 0)
  227.  
  228. ADD_LAST{*listhead.dllhead,itemsize.l} (with #DLL_TRAP_ERRORS = 1)
  229.  
  230. Adds a new (blank) item as the last item in the list. If a function,
  231. it will return true if it successfully added an item, otherwise it returns
  232. false.
  233.  
  234. If an item was added, the current item pointer (your list pointer variable)
  235. will point to the newly added item.
  236.  
  237.  Same as ADD_ITEM, except that it inserts the new item as the last item in
  238. the list.
  239.  
  240. 4.4. CLEAR_LIST
  241.  
  242. CLEAR_LIST{*listhead.dllhead}
  243.  
  244.  Kills all the items in the list, but keeps the list head information
  245.  so that you can resuse the list (ie, ready for ADD_ITEM).
  246.  
  247. 4.5. FIRST_ITEM
  248.  
  249. ret.l = FIRST_ITEM{*listhead.dllhead}
  250.  
  251. Sets the current item pointer for the list to the first item in the list if
  252. available. Returns true if successful, otherwise returns false.
  253.  
  254. 4.6. GET_CURRENT_ITEM
  255.  
  256. *ItemPointer.dll = GET_CURRENT_ITEM{*listhead.dllhead}
  257.  
  258. Returns the address of the current item.
  259.  
  260. Useful only when a common routine is being used to handle multiple lists.
  261.  
  262. 4.7. GET_LIST_POS
  263.  
  264. position.l = GET_LIST_POS{*listhead.dllhead}
  265.  
  266. Returns the position of the current item in the list. The first item
  267. is number 1.
  268.  
  269. Doesn't change the list's current item pointer.
  270.  
  271. 4.8. GET_LIST_SIZE
  272.  
  273. Count.l = GET_LIST_SIZE{*listhead.dllhead}
  274.  
  275. Returns the number of items in the list.
  276.  
  277. Doesn't change the list's current item pointer.
  278.  
  279. 4.9. ITEM_STACK_SIZE
  280.  
  281. ret.b = ITEM_STACK_SIZE{*listhead.dllhead,depth.l}  (with #DLL_TRAP_ERRORS = 0)
  282.  
  283. ITEM_STACK_SIZE{*listhead.dllhead,depth.l}  (with #DLL_TRAP_ERRORS = 1)
  284.  
  285. Sets the list stack size (for PUSH_ITEM, and POP_ITEM) to depth. Make
  286. sure never to push more items than there is room for on the list stack.
  287.  
  288. Default is 8.
  289.  
  290. If there are any positions pushed onto the stack when this command is
  291. executed, they will be discarded and the item stack will be reset at the
  292. beginning of the new sized item stack.
  293.  
  294. Doesn't change the list's current item pointer.
  295.  
  296. See also PUSH_ITEM, POP_ITEM
  297.  
  298. 4.10. INIT_LIST
  299.  
  300. *Listhead.dllhead = INIT_LIST{&*listitem.dll,itemsize.l}
  301.  
  302. Initilizes the list for the first time.  After calling this you need to
  303. set the string positions...see SET_STRING_POSITIONS.  Returns the head of
  304. the list if succesful otherwise returns 0.
  305.  
  306. Always call in the style of the following line:
  307.  
  308. *listhead.dllhead=INIT_LIST{&*blah_item,sizeof .blah_item_type}
  309.  
  310. because you need to save the return head of the list address to pass
  311. to the other routines.
  312.  
  313. 4.11. KILL_ITEM
  314.  
  315. KILL_ITEM{*listhead.dllhead}
  316.  
  317. Kills the item at the current list position.
  318.  
  319. The list's current item pointer will point at the previous item (if any) or
  320. at the list header if the first item was killed.
  321.  
  322. 4.12. LAST_ITEM
  323.  
  324. ret.b = LAST_ITEM{*listhead.dllhead}
  325.  
  326. Sets the current item pointer for the list to the last item in the list if
  327. available.  Returns true if successful, otherwise returns false.
  328.  
  329. 4.13. NEXT_ITEM
  330.  
  331. ret.b = NEXT_ITEM{*listhead.dllhead}
  332.  
  333. Sets the current item pointer for the list to the next item in the list if
  334. available.  Returns true if successful, otherwise returns false.
  335.  
  336. This is always a function.
  337.  
  338. 4.14. NO_MORE_ITEMS
  339.  
  340. NO_MORE_ITEMS{*listhead.dllhead}
  341.  
  342. Sets the list's current item pointer to the last item in the list,
  343. if available, but doesn't care if the list is empty.
  344.  
  345. Used to terminate loops of the form
  346.  
  347.      RESET_LIST{*MyList}
  348.  
  349.      While NEXT_ITEM{*MyList}
  350.  
  351.        If *MyItem\Key = WantedValue
  352.  
  353.          ; Process the item
  354.  
  355.          NO_MORE_ITEMS{*MyList}
  356.  
  357.        Endif
  358.  
  359.      Wend
  360.  
  361.      ; The wanted item is no longer available
  362.  
  363.  
  364. Effectively identical to LAST_ITEM, but doesn't need a dummy return code
  365.  
  366. 4.15. POP_ITEM
  367.  
  368. POP_ITEM{*listhead.dllhead}
  369.  
  370. Pop's the list's current item pointer from the list's item stack. Make
  371. sure there is an item on the list stack to 'pop'.
  372.  
  373. Because the list can have been sorted between the push and pop commands
  374. the internal current item position pointer can have been corrupted.  This
  375. command includes an embedded RESET_LIST_POS to recalculate this pointer.
  376. This can be slow for large lists
  377.  
  378. See also ITEM_STACK_SIZE, PUSH_ITEM
  379.  
  380. 4.16. PREV_ITEM
  381.  
  382. ret.b = PREV_ITEM{*listhead.dllhead}
  383.  
  384. Sets the current item pointer for the list to the previous item in the
  385. list if available.  Returns true if successful, otherwise returns false.
  386.  
  387. 4.17. PUSH_ITEM
  388.  
  389. PUSH_ITEM{*listhead.dllhead}
  390.  
  391. Pushes the list's current item pointer onto the list's item stack. Make
  392. sure you don't push more items than the list stack can hold.
  393.  
  394. See also ITEM_STACK_SIZE, POP_ITEM.
  395.  
  396. 4.18. RESET_LIST_POS
  397.  
  398. RESET_LIST_POS{*listhead.dllhead}
  399.  
  400. Calculates the list position for the current list item.
  401. Should only be needed by POP_ITEM.
  402.  
  403. Does a brute-force "start at the beginning and compare headers until
  404. the current one is found" search which can be slow for big arrays.
  405.  
  406. 4.19. RESET_LIST
  407.  
  408. RESET_LIST{*listhead.dllhead}
  409.  
  410. Resets the list to the head item (makes the next NEXT_ITEM return the
  411. first item in the list if available!).
  412.  
  413. 4.20. SET_LIST_POS
  414.  
  415. ret.b = SET_LIST_POS{*listhead.dllhead,listpos.l} (with #DLL_TRAP_ERRORS = 0)
  416.  
  417. SET_LIST_POS{*listhead.dllhead,listpos.l} (with #DLL_TRAP_ERRORS = 1)
  418.  
  419. Sets the list's current item pointer to the item in the list
  420. at the supplied listpos position.
  421.  
  422. This takes into account the current list position at the time the
  423. command was issued and takes the shortest of the following five
  424. options:
  425.  
  426. o  Start at the front and count forwards
  427. o  Start at the current position and count backwards
  428. o  Stay in the current position
  429. o  Start at the current position and count forwards
  430. o  Start at the end of the list and count backwards
  431.  
  432. 4.21. SET_STRING_POSITIONS
  433.  
  434. SET_STRING_POSITIONS{*listhead.dllhead}
  435.  
  436. Records the positions of all blitz string pointers, by looking through the
  437. data section of the item for non negative values (-1 only). Before calling
  438. this you MUST set all the non string variables in your head item to -1,
  439. and all the string variables to "", to allow this function to tell the
  440. difference and record the positions of strings, so KILL_ITEM can properly
  441. deallocate the memory taken up by them.
  442.  
  443. 4.22. SORT_LIST_ASCENDING
  444.  
  445. SORT_LIST_ASCENDING{*listhead.dllhead,entrypath.l,vartype.l}
  446.  
  447. Sorts the list items into ascending order using an insert sort. Entrypath
  448. should be the offset in bytes of the variable in the item to use for sort
  449. the list (ie, use sizeof .myitem\\mysortvarname).  Vartype should be one of
  450. the following constants to define the variable type pointed to by the
  451. entrypath.
  452.  
  453. #VARTYPE_BTYE, #VARTYPE_WORD, #VARTYPE_LONG, #VARTYPE_QUICK, #VARTYPE_FLOAT
  454.  
  455. The sort routine will corrupt the internal list position indicator.   For
  456. this reason the sort routine includes a RESET_LIST, which forces the list
  457. position indicator to zero.
  458.  
  459. 4.23. SORT_LIST_DESCENDING
  460.  
  461. SORT_LIST_DESCENDING{*listhead.dllhead,entrypath.l,vartype.l}
  462.  
  463. Sorts the list items into descending order using an insert sort. Entrypath
  464. should be the offset in bytes of the variable in the item to use for sort
  465. the list (ie, use sizeof .myitem\\mysortvarname).  Vartype should be one of
  466. the following constants to define the variable type pointed to by the
  467. entrypath.
  468.  
  469. #VARTYPE_BTYE, #VARTYPE_WORD, #VARTYPE_LONG, #VARTYPE_QUICK, #VARTYPE_FLOAT
  470.  
  471. The sort routine will corrupt the internal list position indicator.   For
  472. this reason the sort routine includes a RESET_LIST, which forces the list
  473. position indicator to zero.
  474.  
  475. 4.23. STRING_SORT_ASCENDING
  476.  
  477. STRING_SORT_ASCENDING{*listhead.dllhead,entrypath.l}
  478.  
  479. Sorts the list items into ascending order using an insert sort. Entrypath
  480. should be the offset in bytes of the variable in the item to use for sort
  481. the list (ie, use sizeof .myitem\\mysortvarname).   This variable MUST be a
  482. string variable
  483.  
  484. The sort routine will corrupt the internal list position indicator.   For
  485. this reason the sort routine includes a RESET_LIST, which forces the list
  486. position indicator to zero.
  487.  
  488. 4.24. STRING_SORT_DESCENDING
  489.  
  490. STRING_SORT_DESCENDING{*listhead.dllhead,entrypath.l}
  491.  
  492. Sorts the list items into descending order using an insert sort. Entrypath
  493. should be the offset in bytes of the variable in the item to use for sort
  494. the list (ie, use sizeof .myitem\\mysortvarname).   This variable MUST be a
  495. string variable
  496.  
  497. The sort routine will corrupt the internal list position indicator.   For
  498. this reason the sort routine includes a RESET_LIST, which forces the list
  499. position indicator to zero.
  500.  
  501. 5. Advantages of DLL over standard lists
  502.  
  503. DLL has a number of advantages over the original Blitz Lists.
  504.  
  505. 1. You do not need to define a maximum size for the list.
  506.  
  507. 2. Since the lists are referenced  by pointers, you can easily define common
  508.    routines to handle multiple lists.
  509.  
  510. 3. New functions GET_LIST_POS, GET_LIST_SIZE and SET_LIST_POS  mean that you
  511.    do not need to keep track of item counts or positions
  512.  
  513. 4. There is an internal position indicator which greatly speeds up moving
  514.    around the list with SET_LIST_POS.
  515.  
  516. 6. Disadvantages of DLL
  517.  
  518. There are two disadvantages to using DLL rather than Blitz Lists
  519.  
  520. 1. Since DLL is a set of functions, written in Blitz Basic and Blitz Lists
  521.    are in a library written in Assembler, DLL is about 10% slower than
  522.    Blitz Lists.
  523.  
  524. 2. DLL is more complicated to initilize than Blitz Lists.
  525.  
  526.    If you are familiar with the use of pointers and NewTypes, there should
  527.    be no real problems.
  528.  
  529.    If Pointers and NewTypes are foreign languages, simply follow the
  530.    syntax given.   The most important points to remember are that your
  531.    List Name and Item Name must begin with an *, (which defines a pointer)
  532.    and the INIT_LIST command must have an & in front of the *ItemName
  533.    to pass the address of the pointer.
  534.  
  535.    The rest is simply calling functions.
  536.  
  537. 7. QuickSort Routines
  538.  
  539. These routines are extra sort routines which are much faster than the
  540. 2 included in DLL, provided a large number of items are being sorted.
  541. For small lists (less than 3000 items) the standard sort routines
  542. are quicker.
  543.  
  544. These routines are kept in a seperate include (DLLSORT.bb2) so people who
  545. do not need to sort lists may use the list routines without these extra
  546. routines taking up space. You need to include DLL.bb2 before including
  547. DLLSORT.bb2.
  548.  
  549. These routines require extra memory (just 4*number of items in list as it
  550. uses a seperate list to sort faster, so a 200 item list would require an
  551. extra 800 bytes for the temporary list) and lots of stack space, so make
  552. sure you have plenty of stack space free before calling them.
  553.  
  554.  
  555. QUICK_SORT_LIST_ASCENDING{*listhead.dllhead,entrypath.l,vartype.l}
  556. QUICK_SORT_LIST_DESCENDING{*listhead.dllhead,entrypath.l,vartype.l}
  557.  
  558. These routines perform a quick sort on the list.
  559.  
  560. See SORT_LIST_ASCENDING for more info on the parameters.
  561.  
  562. For a quick string sort, use the constant #VARTYPE_STRING
  563.  
  564. Both quick sort routines will corrupt the internal current item position
  565. indicator so a RESET_LIST{} is included to force the pointer to a correct
  566. value.
  567.  
  568. 7.  Variable size items
  569.  
  570. You can have indvidual items of different sizes, but you can't access
  571. variables outside of your smaller type.
  572.  
  573. You must not cut any variable off with your smaller size, it must be
  574. big enough to hold at least the dllnode header and must always end on
  575. a variable, not in the middle of one. (especially NOT string variables
  576. as when the item is cleared it will attempt to free the string if you have
  577. left the start of a string variable inside the item, whether you have
  578. left the whole string variable in or not!!!).
  579.  
  580. When doing the INIT_LIST, the size specified MUST be big enough to include
  581. all string variables.
  582.  
  583.  
  584. 8. How to handle multiple lists with a common routine
  585.  
  586. Assume that you have three lists and want to perform some common operations
  587. on them.
  588.  
  589. With standard Blitz Lists, you must either replicate the common code for
  590. each list or else set up a flag (or ListNumber) to show which list is
  591. being processed and then do things like
  592.  
  593. Select ListNumber
  594.    Case 1
  595.      If NextItem(List1()) then ; do something
  596.    Case 2
  597.      If NextItem(List2()) then ; do something
  598.    Case 3
  599.      If NextItem(List3()) then ; do something
  600. End Select
  601.  
  602. Then, if you want to add another list, you need to modify all the select
  603. blocks.
  604.  
  605.  
  606. With DLL, you simply need to define a dummy list as:
  607.  
  608. DefType.dllhead *TheList
  609.  
  610. and a dummy item
  611.  
  612. Deftype.Item *TheItem
  613.  
  614. Your Item NewType should contain a node.dll as the first variable, plus
  615. any common variables needed by the common routine.
  616.  
  617. Then, if you are processing *List1, *List2 and *List3 you need to
  618. execute the following code
  619.  
  620. *TheList = *List1
  621. gosub common_routine
  622.  
  623. *TheList = *List2
  624. gosub common_routine
  625.  
  626. *TheList = *List3
  627. gosub common_routine
  628.  
  629.  
  630. and the common routine can now perform all operations on *TheList.
  631.  
  632. However, if the operation changes the current item pointer, the common
  633. routine won't know which item pointer has changed.  To get the pointer
  634. address, the common routine should use the GET_CURRENT_ITEM{} function:
  635.  
  636. If NEXT_ITEM{*TheList}
  637.    *TheItem = GET_CURRENT_ITEM{*TheList}
  638.    Value = *TheItem\Value
  639. endif
  640.  
  641. Adding another list requires no changes to the common routine
  642.  
  643.  
  644. 9. Using DLL lists with GTListviews"
  645.  
  646. To use a DLL list with a GTListview you MUST set up the type for
  647. the items in your DLL list to look like this:
  648.  
  649.    NEWTYPE.dllgtlvitem
  650.       node.dll       ; Always the first item in DLL lists
  651.       pad.w          ; The node must be followed by a word variable
  652.       text.s         ; Followed by the text to be displayed in the GTListview
  653.       ; Anything else you want to add can be at the end of the item
  654.    END NEWTYPE
  655.  
  656. If you do not set up the items like this you risk either not seeing
  657. anything in the GTListview or perhaps your program will crash.
  658.  
  659. Obviously the command for creating a GTListview requires that the list
  660. parameter is a regular Blitz list array. Since we will not be using that
  661. list with the GTListview we can create a dummy list, with no special
  662. newtype.
  663.  
  664. However, this list MUST NEVER have any items in it - if you do intend on
  665. having items in the dummy list, you must make sure that it has a newtype
  666. which you would normally use for Blitz list arrays being displayed in
  667. GTListviews (same as the above newtype but without the "node.dll" field).
  668.  
  669. When working with DLL lists and GTListviews, you generally need to use
  670. GTSetAttrs, since all the specific GTListview commands require list arrays
  671. as parameters.
  672.  
  673. So, the full steps involved would look something like this:
  674.  
  675.    ; Newtype for allowing us to display items in a GTListview
  676.    NEWTYPE.dllgtlvitem
  677.       node.dll       ; Always the first item in DLL lists
  678.       pad.w          ; The node must be followed by a word variable
  679.       text.s         ; Followed by the text to be displayed in the GTListview
  680.       ; Anything else you want to add can be at the end of the item
  681.    END NEWTYPE
  682.  
  683.    ; Our variables for working with the DLL list
  684.    DEFTYPE.dllhead     *listhead
  685.    DEFTYPE.dllgtlvitem *myitem
  686.  
  687.    ; Initialise DLL list here
  688.    ; Add items as required here
  689.  
  690.    ; Create dummy list array. This one will always remain empty
  691.    ; so it does not matter about the type used.
  692.    Dim List dummy.w(0)
  693.  
  694.    ; Create GTListview and then use the DLL list straight away
  695.    GTListview gtlist,id,x,y,w,h,text$,flags,dummy()
  696.    GTSetAttrs gtlist,id,#GTLV_Labels,*listhead
  697.  
  698.    ; Open window and attach gtlist to it
  699.    ; We can also set the DLL list onto the GTListview after we have
  700.    ; attached the gtlist to a window using the same GTSetAttrs line
  701.    ; as above. The GTListview will automatically be redrawn if it
  702.    ; is in a gtlist that is attached to a window
  703.    GTSetAttrs gtlist,id,#GTLV_Labels,*listhead
  704.  
  705.    ; If we want to modify the DLL list, we must do the same as we
  706.    ; would normally have to do with GTListviews - detach the list
  707.    ; from the GTListview, modify the list, then re-attach the list
  708.  
  709.    ; Detach DLL list from GTListview
  710.    GTChangeList gtlist,id
  711.  
  712.    ; Modify DLL list in here
  713.  
  714.    ; Re-attach DLL list to GTListview
  715.    GTSetAttrs gtlist,id,#GTLV_Labels,*listhead
  716.  
  717. Apart from the different method used to attach the DLL list to the
  718. GTListview, and the slightly different newtype that is required, everything
  719. else is the same as when you are using Blitz list arrays. See the example
  720. program, dllexample.bb2, this shows you how to add a DLL list to a
  721. GTListview.
  722.  
  723. 10. Bugs  :(
  724.  
  725.    As far as I am aware, there are no bugs.   Anything that looks like a bug
  726.    is actually the way it is supposed to work :-)
  727.  
  728.    If you don't like the way it's supposed to work, please send an email to
  729.    edgewater@shoalhaven.net.au with a subject line of DLL BUGS
  730.  
  731.    Don't simply say "It doesn't work"  because I will simply say "Yes it does".
  732.    Make sure you have tried your code with the latest version of these routines.
  733.  
  734.    Please provide specific details of what you wanted it to do, what it did,
  735.    whether it does it every time and the simplest version of your source
  736.    code which contains the problem.
  737.  
  738.    If I can compile it, I can diagnose it (Note:  Not Fix it!)
  739.  
  740. 11. Thanks
  741.  
  742.    I'd like to take a moment to thank:
  743.  
  744.    Dave Newton   for the original code.
  745.  
  746.    John Mason    for suggestions and ideas on strings!
  747.  
  748.    David McMinn  for ideas on attaching DLL Lists to GTListviews
  749.  
  750.    And, in general, everybody on the Blitz-list
  751.